﻿using System.Collections.Generic;

namespace Borg.Framework
{
    public class DependentPlug
    {
        private readonly List<SlotInfo> _cancelledSlots = new List<SlotInfo>();
        private readonly PlugInfo _plug;
        private readonly List<SlotInfo> _slots = new List<SlotInfo>();

        public DependentPlug(PlugInfo plug, IEnumerable<SlotInfo> slots)
        {
            _plug = plug;
            plug.Plugging += PlugPlugging;

            foreach (var si in slots)
            {
                _slots.Add(si);
                si.Plugged += SlotPlugged;
            }
        }

        public void Detach()
        {
            _plug.Plugging -= PlugPlugging;

            foreach (var si in _slots)
                si.Plugged -= SlotPlugged;
        }

        private void PlugPlugging(object s, CancelPlugEventArgs args)
        {
            foreach (var si in _slots)
            {
                if (si.PluggedPlugInfos.Count == 0)
                {
                    args.Cancel = true;
                    si.Open();
                }

                if (args.Cancel)
                    _cancelledSlots.Add(args.SlotInfo);
            }
        }

        public void QueueEmptied(object s, TaskEventArgs args)
        {
            Runtime.TaskQueue.QueueEmptied -= QueueEmptied;

            foreach (var si in _cancelledSlots)
                _plug.Plug(si);
        }

        private void SlotPlugged(object sender, PlugEventArgs args)
        {
            _slots.Remove(args.SlotInfo);
            args.SlotInfo.Plugged -= SlotPlugged;

            if (_slots.Count == 0)
                Runtime.TaskQueue.QueueEmptied += QueueEmptied;
        }
    }
}

